package aipserver

import (
	"apedge/dao"
	"apedge/dto"
	"apedge/pkg/common"
	"apedge/pkg/database"
	"apedge/pkg/protocol"
	"encoding/json"
	"time"
)

func CreateNodeGroup(req dto.CreateNodeGroupReq, userInfo *protocol.UserInfoAAA) (int64, error) {
	var err error
	nodeIds, err := json.Marshal(req.NodeIds)
	if err != nil {
		return 0, err
	}

	tx := database.Db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	// 名字是否存在
	exist, err := CheckNodeGroupNameExist(tx, req.Name)
	if err != nil {
		tx.Rollback()
		return 0, err
	}
	if exist {
		tx.Rollback()
		return 0, common.ErrNodeExist
	}

	now := time.Now()
	t := &dao.ApedgeNodeGroup{
		OrgId:     int64(userInfo.OrgId),
		GroupId:   int64(userInfo.GroupId),
		UserId:    int64(userInfo.UserId),
		UserName:  userInfo.UserName,
		Name:      req.Name,
		Describe:  req.Describe,
		Type:      req.NodeType,
		NodeIds:   string(nodeIds),
		CreatedAt: &now,
		UpdatedAt: &now,
	}

	if err = t.Save(tx); err != nil {
		tx.Rollback()
		return 0, err
	}
	return t.ID, tx.Commit().Error
}

func GetNodeGroupList(req dto.GetNodeGroupListReq, userInfo *protocol.UserInfoAAA) ([]dto.OutApedgeNodeGroupItem, int64, error) {
	var err error
	var items []dao.ApedgeNodeGroup
	var count int64
	var t dao.ApedgeNodeGroup

	tx := database.Db
	items, count, err = t.GetNodeGroupList(tx, req.PageNum, req.PageSize, req.Name, req.Sort, userInfo)
	if err != nil {
		return nil, 0, err
	}
	outPutList := []dto.OutApedgeNodeGroupItem{}
	for _, item := range items {
		outItem, err := GenOutApedgeNodeGroupItem(item)
		if err != nil {
			return nil, 0, err
		}
		outPutList = append(outPutList, outItem)
	}
	return outPutList, count, err
}

func GetNodeGroupDetail(id int64) (*dto.OutApedgeNodeGroupItem, error) {
	var err error
	var item *dao.ApedgeNodeGroup
	var outItem dto.OutApedgeNodeGroupItem

	tx := database.Db
	t := &dao.ApedgeNodeGroup{
		ID: id,
	}

	item, err = t.GetNodeGroupById(tx)
	if err != nil {
		if err.Error() == common.DB_ERR_RECORD_NOT_FOUND {
			return nil, common.ErrNodeNotExist
		}
		return nil, err
	}

	// 节点组包含的所有节点信息
	nodeIds := []string{}
	err = json.Unmarshal([]byte(item.NodeIds), &nodeIds)
	if err != nil {
		return nil, err
	}
	node := &dao.ApedgeNode{}
	nodes, err := node.GetNodeListByNodeIds(tx, nodeIds)
	if err != nil {
		return nil, err
	}
	outPutNodeList := []dto.OutApedgeNodeItem{}
	for _, n := range nodes {
		outNodeItem, err := GenOutApedgeNodeItem(n)
		if err != nil {
			return nil, err
		}
		outPutNodeList = append(outPutNodeList, outNodeItem)
	}
	// 节点组包含的服务信息
	serviceSet := make(map[string]bool)
	serviceIds := []string{}
	ns := dao.ApedgeServiceNode{}
	nsList, err := ns.GetListByNodeIds(tx, nodeIds)
	if err != nil {
		return nil, err
	}
	for _, n := range nsList {
		serviceSet[n.ServiceId] = true
	}
	for k, _ := range serviceSet {
		serviceIds = append(serviceIds, k)
	}
	svcTemp := dao.ApedgeInference{}
	svcList, err := svcTemp.GetListByServiceIds(tx, serviceIds)
	if err != nil {
		return nil, err
	}
	outPutSvcList := []dto.OutApedgeInferenceItem{}
	for _, item := range svcList {
		outItem, err := GenOutApedgeInferenceItem(item)
		if err != nil {
			return nil, err
		}
		outPutSvcList = append(outPutSvcList, outItem)
	}

	outItem, err = GenOutApedgeNodeGroupItem(*item)
	outItem.Nodes = outPutNodeList
	outItem.Services = outPutSvcList
	if err != nil {
		return nil, err
	}
	return &outItem, nil
}

func DelNodeGroup(id int64) error {

	tx := database.Db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	t := dao.ApedgeNodeGroup{
		ID: id,
	}
	_, err := t.GetNodeGroupById(tx)
	if err != nil {
		if err.Error() == common.DB_ERR_RECORD_NOT_FOUND {
			return common.ErrNodeNotExist
		}
		return err
	}

	err = t.DeleteById(tx)
	if err != nil {
		return err
	}
	return tx.Commit().Error
}
